package com.liu.mybatisPlus.poke.service.impl;

import com.liu.mybatisPlus.poke.entity.base.Poke;
import com.liu.mybatisPlus.poke.service.PokeService;
import com.liu.mybatisPlus.poke.service.SyncPokeService;
import com.liu.qqRobot.poke.callable.SyncPokeCallable;
import com.liu.qqRobot.poke.runnable.SavePokeImgRunnable;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class SyncPokeServiceImpl implements SyncPokeService {

    @Resource
    private PokeService pokeService;

    @Override
    public void syncPoke() throws IOException, InterruptedException {
        List<String> regionList = Arrays.asList("关都", "城都", "丰缘", "神奧", "合眾", "卡洛斯", "阿羅拉", "伽勒尔", "帕底亚");
        // 创建多线程
        CountDownLatch countDownLatch = new CountDownLatch(regionList.size());
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor((int) countDownLatch.getCount(),
                (int) countDownLatch.getCount() + 1, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50),
                Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
        String url = "https://wiki.52poke.com/zh-hans/%E5%AE%9D%E5%8F%AF%E6%A2%A6%E5%88%97%E8%A1%A8%EF%BC%88%E6%8C%89%E5%85%A8%E5%9B%BD%E5%9B%BE%E9%89%B4%E7%BC%96%E5%8F%B7%EF%BC%89";
        Connection connect = Jsoup.connect(url);
        Element body = connect.get().body();
        List<Poke> pokeList = new ArrayList<>();
        List<Poke> existPokeList = pokeService.list();
        Map<Integer, Poke> existPokeMap = existPokeList.stream().collect(Collectors.toMap(Poke::getWikiId, p -> p));
        List<Future<List<Poke>>> threadResult = new ArrayList<>();
        regionList.forEach(region -> {
            threadResult.add(threadPoolExecutor.submit(new SyncPokeCallable(body, region, countDownLatch, existPokeMap)));
        });
        countDownLatch.await();
        threadResult.forEach(thread -> {
            try {
                pokeList.addAll(thread.get());
            } catch (InterruptedException | ExecutionException e) {
                throw new RuntimeException(e);
            }
        });
        // 保存图片到本地
        // 创建多线程
        CountDownLatch saveImgCountDownLatch = new CountDownLatch(pokeList.size());
        ThreadPoolExecutor saveImgThreadPoolExecutor = new ThreadPoolExecutor(10, 20,
                1, TimeUnit.MINUTES, new ArrayBlockingQueue<Runnable>(50),
                Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
        pokeList.forEach(poke -> {
            saveImgThreadPoolExecutor.submit(new SavePokeImgRunnable(poke, saveImgCountDownLatch));
        });
        saveImgCountDownLatch.await();
        List<Poke> insertList = pokeList.stream().filter(p -> p.getId() == null).collect(Collectors.toList());
        pokeService.saveBatch(insertList);
        List<Poke> updateList = pokeList.stream().filter(p -> p.getId() != null).collect(Collectors.toList());
        pokeService.updateBatchById(updateList);
    }
}
